
#pragma once

#include "../server/TcpServer.h"
#include "Request.h"
#include "Response.h"

using HttpRecvStatus = enum { RECV_HTTP_ERROR, RECV_HTTP_LINE, RECV_HTTP_HEAD, RECV_HTTP_BODY, RECV_HTTP_OVER };

class HttpContext {
public:
    HttpContext() : resp_status_(200), recv_status_(RECV_HTTP_LINE) {}

private:
    bool ParseHttpLine(Buffer* buffer) {
        if (recv_status_ != RECV_HTTP_LINE)
            return false;
        // 查找 "\r\n"
        const char* crlf = buffer->FindCRLF();
        if (!crlf) {
            // 数据不完整，等待更多数据
            if (buffer->ReadableBytes() > MAX_LINE) {
                recv_status_ = RECV_HTTP_ERROR;
                resp_status_ = 414;  // URI TOO LONG
            }
            return false;
        }

        size_t line_len = crlf - buffer->Peek();
        std::string line(buffer->Peek(), line_len);
        buffer->Retrieve(line_len + 2);

        // 解析请求行
        size_t pos1 = line.find(' ');
        if (pos1 == std::string::npos) {
            recv_status_ = RECV_HTTP_ERROR;
            resp_status_ = 400;  // BAD REQUEST
            return false;
        }

        size_t pos2 = line.find(' ', pos1 + 1);
        if (pos2 == std::string::npos) {
            recv_status_ = RECV_HTTP_ERROR;
            resp_status_ = 400;  // BAD REQUEST
            return false;
        }

        std::string method = line.substr(0, pos1);
        std::string url = line.substr(pos1 + 1, pos2 - pos1 - 1);
        std::string version = line.substr(pos2 + 1);

        request_.SetMethod(method);
        request_.SetUrl(url);
        request_.SetVersion(version);

        recv_status_ = RECV_HTTP_HEAD;
        return true;
    }

    bool ParseHttpHeader(Buffer* buffer) {
        if (recv_status_ != RECV_HTTP_HEAD)
            return false;

        // 循环解析所有头部行
        while (buffer->ReadableBytes() > 0) {
            const char* crlf = buffer->FindCRLF();
            if (!crlf) {
                // 数据不完整，等待更多数据
                if (buffer->ReadableBytes() > MAX_LINE) {
                    recv_status_ = RECV_HTTP_ERROR;
                    resp_status_ = 414;  // URI TOO LONG
                }
                return false;
            }

            size_t line_len = crlf - buffer->Peek();
            std::string line(buffer->Peek(), line_len);

            // 检查空行 - 头部结束
            if (line.empty()) {
                buffer->Retrieve(2);
                recv_status_ = RECV_HTTP_BODY;
                return true;
            }

            buffer->Retrieve(line_len + 2);

            // 解析头部字段
            size_t pos = line.find(':');
            if (pos == std::string::npos) {
                recv_status_ = RECV_HTTP_ERROR;
                resp_status_ = 400;  // BAD REQUEST
                return false;
            }

            std::string key = line.substr(0, pos);
            std::string value = line.substr(pos + 2);

            std::cout << "------------------" << std::endl;
            std::cout << key << ": " << value << std::endl;
            std::cout << "------------------" << std::endl;

            request_.AddHeader(key, value);
        }

        return false;  // 数据不完整
    }

    bool ParseHttpBody(Buffer* buffer) {
        if (recv_status_ != RECV_HTTP_BODY)
            return false;

        size_t content_length = request_.ContentLength();
        if (content_length == 0) {
            // 没有正文
            recv_status_ = RECV_HTTP_OVER;
            return true;
        }

        // 计算还需要接收的正文长度
        size_t body_received = request_.body_.size();
        size_t body_remaining = content_length - body_received;

        if (buffer->ReadableBytes() < body_remaining) {
            // 数据不完整，读取所有可用数据
            std::string body_part(buffer->Peek(), buffer->ReadableBytes());
            request_.body_.append(body_part);
            buffer->Retrieve(buffer->ReadableBytes());
            return false;
        }

        // 数据完整，读取剩余正文
        std::string body(buffer->Peek(), body_remaining);
        request_.SetBody(body);
        buffer->Retrieve(body_remaining);

        LOG_INFO("request body:%s", body.c_str());
        recv_status_ = RECV_HTTP_OVER;
        return true;
    }

public:
    void ParseRequest(Buffer* buffer) {
        // 分阶段处理，数据流式处理
        switch (recv_status_) {
            case RECV_HTTP_LINE:
                ParseHttpLine(buffer);
            case RECV_HTTP_HEAD:
                ParseHttpHeader(buffer);
            case RECV_HTTP_BODY:
                ParseHttpBody(buffer);
            default:
                break;
        }
    }

    Request& GetRequest() { return request_; }
    Response GetResponse() { return response_; }

    bool IsComplete() const { return recv_status_ == RECV_HTTP_OVER; }
    bool HasError() const { return recv_status_ == RECV_HTTP_ERROR; }
    int GetRespStatus() const { return resp_status_; }

    void Reset() {
        resp_status_ = 200;
        recv_status_ = RECV_HTTP_LINE;
        request_.Reset();
    }

private:
    static const size_t MAX_LINE = 8192;  // 最大行长度

    int resp_status_;
    HttpRecvStatus recv_status_;
    Request request_;
    Response response_;
};